package com.zhm.demo.netty.handler;

import com.zhm.demo.netty.protobuf.DeviceBean;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.springframework.util.ObjectUtils;

public class HeartbeatHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof DeviceBean.WrapperMessage) {
            handlePing(ctx);
            if (ObjectUtils.isEmpty(evt)) {
                return;
            } else {
                super.channelRead(ctx, evt);
            }
        } else if (evt instanceof IdleStateEvent) {
            handleIdleStateEvent(ctx, (IdleStateEvent) evt);
        } else {
            super.channelRead(ctx, evt);
        }
    }

    private void handlePing(ChannelHandlerContext ctx) {
        // 处理心跳请求，发送心跳响应
        DeviceBean.WrapperMessage pong = DeviceBean
                .WrapperMessage
                .newBuilder()
                .setType(DeviceBean.WrapperMessage.MessageType.Pong)
                .setPong(DeviceBean.Pong.newBuilder().setType("服务器的Pong"))
                .build();
        ChannelFuture channelFuture = ctx.writeAndFlush(pong);
        channelFuture.addListener((future) -> {
            if (future.isSuccess()) {
                // 异步操作成功，连接有效
                System.out.println("Server Heartbeat sent successfully");
            } else {
                // 异步操作失败，连接无效，可以在这里处理连接无效的逻辑
                System.out.println("Server Failed to send heartbeat, marking connection as invalid");
            }
        });
    }

    private void handleIdleStateEvent(ChannelHandlerContext ctx, IdleStateEvent evt) {
        if (evt.state() == IdleState.READER_IDLE) {
            System.out.println("客户端长时间未通信，可能已经宕机，关闭链路");
            ctx.close();
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端已连接");
        super.channelActive(ctx);
//        handlePing(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端已关闭连接");
        super.channelInactive(ctx);
    }
}
